/*
* Copyright (c) 2019 MediaTek Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#pragma once

/* #include <platform/mt_gpio.h> */
/* #include <platform/mt_i2c.h> */
/* #include <platform/mt_pmic.h> */
#include <string.h>

/* --------------------------------------------------------------------------- */

#ifndef ARY_SIZE
#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0])))
#endif

/* --------------------------------------------------------------------------- */

/* common enumerations */

typedef enum {
    LCM_TYPE_DBI = 0,
    LCM_TYPE_DPI,
    LCM_TYPE_DSI
} LCM_TYPE;


typedef enum {
    LCM_CTRL_NONE = 0,
    LCM_CTRL_SERIAL_DBI,
    LCM_CTRL_PARALLEL_DBI,
    LCM_CTRL_GPIO
} LCM_CTRL;


typedef enum {
    LCM_POLARITY_RISING = 0,
    LCM_POLARITY_FALLING = 1
} LCM_POLARITY;


typedef enum {
    LCM_CLOCK_PHASE_0 = 0,
    LCM_CLOCK_PHASE_90 = 1
} LCM_CLOCK_PHASE;


typedef enum {
    LCM_COLOR_ORDER_RGB = 0,
    LCM_COLOR_ORDER_BGR = 1
} LCM_COLOR_ORDER;


typedef enum {
    LCM_DRIVING_CURRENT_DEFAULT,
    LCM_DRIVING_CURRENT_8MA = (1 << 0),
    LCM_DRIVING_CURRENT_4MA = (1 << 1),
    LCM_DRIVING_CURRENT_2MA = (1 << 2),
    LCM_DRIVING_CURRENT_SLEW_CNTL = (1 << 3),
    LCM_DRIVING_CURRENT_6575_4MA = (1 << 4),
    LCM_DRIVING_CURRENT_6575_8MA = (3 << 4),
    LCM_DRIVING_CURRENT_6575_12MA = (2 << 4),
    LCM_DRIVING_CURRENT_6575_16MA = (4 << 4),
    LCM_DRIVING_CURRENT_6MA,
    LCM_DRIVING_CURRENT_10MA,
    LCM_DRIVING_CURRENT_12MA,
    LCM_DRIVING_CURRENT_14MA,
    LCM_DRIVING_CURRENT_16MA,
    LCM_DRIVING_CURRENT_20MA,
    LCM_DRIVING_CURRENT_24MA,
    LCM_DRIVING_CURRENT_28MA,
    LCM_DRIVING_CURRENT_32MA
} LCM_DRIVING_CURRENT;

typedef enum {
    LCM_INTERFACE_NOTDEFINED = 0,
    LCM_INTERFACE_DSI0,
    LCM_INTERFACE_DSI1,
    LCM_INTERFACE_DSI_DUAL,
    LCM_INTERFACE_DPI0,
    LCM_INTERFACE_DPI1,
    LCM_INTERFACE_DBI0
} LCM_INTERFACE_ID;

typedef enum {
    LCM_IOCTL_NULL = 0,
} LCM_IOCTL;

/* DBI related enumerations */

typedef enum {
    LCM_DBI_CLOCK_FREQ_104M = 0,
    LCM_DBI_CLOCK_FREQ_52M,
    LCM_DBI_CLOCK_FREQ_26M,
    LCM_DBI_CLOCK_FREQ_13M,
    LCM_DBI_CLOCK_FREQ_7M
} LCM_DBI_CLOCK_FREQ;


typedef enum {
    LCM_DBI_DATA_WIDTH_8BITS = 0,
    LCM_DBI_DATA_WIDTH_9BITS = 1,
    LCM_DBI_DATA_WIDTH_16BITS = 2,
    LCM_DBI_DATA_WIDTH_18BITS = 3,
    LCM_DBI_DATA_WIDTH_24BITS = 4,
    LCM_DBI_DATA_WIDTH_32BITS = 5
} LCM_DBI_DATA_WIDTH;


typedef enum {
    LCM_DBI_CPU_WRITE_8_BITS = 8,
    LCM_DBI_CPU_WRITE_16_BITS = 16,
    LCM_DBI_CPU_WRITE_32_BITS = 32,
} LCM_DBI_CPU_WRITE_BITS;


typedef enum {
    LCM_DBI_FORMAT_RGB332 = 0,
    LCM_DBI_FORMAT_RGB444 = 1,
    LCM_DBI_FORMAT_RGB565 = 2,
    LCM_DBI_FORMAT_RGB666 = 3,
    LCM_DBI_FORMAT_RGB888 = 4
} LCM_DBI_FORMAT;


typedef enum {
    LCM_DBI_TRANS_SEQ_MSB_FIRST = 0,
    LCM_DBI_TRANS_SEQ_LSB_FIRST = 1
} LCM_DBI_TRANS_SEQ;


typedef enum {
    LCM_DBI_PADDING_ON_LSB = 0,
    LCM_DBI_PADDING_ON_MSB = 1
} LCM_DBI_PADDING;


typedef enum {
    LCM_DBI_TE_MODE_DISABLED = 0,
    LCM_DBI_TE_MODE_VSYNC_ONLY = 1,
    LCM_DBI_TE_MODE_VSYNC_OR_HSYNC = 2,
} LCM_DBI_TE_MODE;


typedef enum {
    LCM_DBI_TE_VS_WIDTH_CNT_DIV_8 = 0,
    LCM_DBI_TE_VS_WIDTH_CNT_DIV_16 = 1,
    LCM_DBI_TE_VS_WIDTH_CNT_DIV_32 = 2,
    LCM_DBI_TE_VS_WIDTH_CNT_DIV_64 = 3,
} LCM_DBI_TE_VS_WIDTH_CNT_DIV;


/* DPI related enumerations */

typedef enum {
    LCM_DPI_FORMAT_RGB565 = 0,
    LCM_DPI_FORMAT_RGB666 = 1,
    LCM_DPI_FORMAT_RGB888 = 2
} LCM_DPI_FORMAT;

typedef enum {
    LCM_SERIAL_CLOCK_FREQ_104M = 0,
    LCM_SERIAL_CLOCK_FREQ_26M,
    LCM_SERIAL_CLOCK_FREQ_52M
} LCM_SERIAL_CLOCK_FREQ;

typedef enum {
    LCM_SERIAL_CLOCK_DIV_2 = 0,
    LCM_SERIAL_CLOCK_DIV_4 = 1,
    LCM_SERIAL_CLOCK_DIV_8 = 2,
    LCM_SERIAL_CLOCK_DIV_16 = 3,
} LCM_SERIAL_CLOCK_DIV;


/* DSI related enumerations */

typedef enum {
    CMD_MODE = 0,
    SYNC_PULSE_VDO_MODE = 1,
    SYNC_EVENT_VDO_MODE = 2,
    BURST_VDO_MODE = 3
} LCM_DSI_MODE_CON;


typedef enum {
    LCM_ONE_LANE = 1,
    LCM_TWO_LANE = 2,
    LCM_THREE_LANE = 3,
    LCM_FOUR_LANE = 4,
} LCM_LANE_NUM;


typedef enum {
    LCM_DSI_FORMAT_RGB565 = 0,
    LCM_DSI_FORMAT_RGB666 = 1,
    LCM_DSI_FORMAT_RGB888 = 2
} LCM_DSI_FORMAT;


typedef enum {
    LCM_DSI_TRANS_SEQ_MSB_FIRST = 0,
    LCM_DSI_TRANS_SEQ_LSB_FIRST = 1
} LCM_DSI_TRANS_SEQ;


typedef enum {
    LCM_DSI_PADDING_ON_LSB = 0,
    LCM_DSI_PADDING_ON_MSB = 1
} LCM_DSI_PADDING;


typedef enum {
    LCM_PACKED_PS_16BIT_RGB565 = 0,
    LCM_LOOSELY_PS_18BIT_RGB666 = 1,
    LCM_PACKED_PS_24BIT_RGB888 = 2,
    LCM_PACKED_PS_18BIT_RGB666 = 3,
    LCM_PACKED_PS_8BIT_SPR = 4,
    LCM_LOOSELY_PS_8BIT_SPR = 5,
    LCM_LOOSELY_PS_10BIT_SPR = 6,
    LCM_PACKED_PS_12BIT_SPR = 7
} LCM_PS_TYPE;

typedef enum {
    LCM_DSI_6589_PLL_CLOCK_NULL = 0,
    LCM_DSI_6589_PLL_CLOCK_201_5 = 1,
    LCM_DSI_6589_PLL_CLOCK_208 = 2,
    LCM_DSI_6589_PLL_CLOCK_214_5 = 3,
    LCM_DSI_6589_PLL_CLOCK_221 = 4,
    LCM_DSI_6589_PLL_CLOCK_227_5 = 5,
    LCM_DSI_6589_PLL_CLOCK_234 = 6,
    LCM_DSI_6589_PLL_CLOCK_240_5 = 7,
    LCM_DSI_6589_PLL_CLOCK_247 = 8,
    LCM_DSI_6589_PLL_CLOCK_253_5 = 9,
    LCM_DSI_6589_PLL_CLOCK_260 = 10,
    LCM_DSI_6589_PLL_CLOCK_266_5 = 11,
    LCM_DSI_6589_PLL_CLOCK_273 = 12,
    LCM_DSI_6589_PLL_CLOCK_279_5 = 13,
    LCM_DSI_6589_PLL_CLOCK_286 = 14,
    LCM_DSI_6589_PLL_CLOCK_292_5 = 15,
    LCM_DSI_6589_PLL_CLOCK_299 = 16,
    LCM_DSI_6589_PLL_CLOCK_305_5 = 17,
    LCM_DSI_6589_PLL_CLOCK_312 = 18,
    LCM_DSI_6589_PLL_CLOCK_318_5 = 19,
    LCM_DSI_6589_PLL_CLOCK_325 = 20,
    LCM_DSI_6589_PLL_CLOCK_331_5 = 21,
    LCM_DSI_6589_PLL_CLOCK_338 = 22,
    LCM_DSI_6589_PLL_CLOCK_344_5 = 23,
    LCM_DSI_6589_PLL_CLOCK_351 = 24,
    LCM_DSI_6589_PLL_CLOCK_357_5 = 25,
    LCM_DSI_6589_PLL_CLOCK_364 = 26,
    LCM_DSI_6589_PLL_CLOCK_370_5 = 27,
    LCM_DSI_6589_PLL_CLOCK_377 = 28,
    LCM_DSI_6589_PLL_CLOCK_383_5 = 29,
    LCM_DSI_6589_PLL_CLOCK_390 = 30,
    LCM_DSI_6589_PLL_CLOCK_396_5 = 31,
    LCM_DSI_6589_PLL_CLOCK_403 = 32,
    LCM_DSI_6589_PLL_CLOCK_409_5 = 33,
    LCM_DSI_6589_PLL_CLOCK_416 = 34,
    LCM_DSI_6589_PLL_CLOCK_422_5 = 35,
    LCM_DSI_6589_PLL_CLOCK_429 = 36,
    LCM_DSI_6589_PLL_CLOCK_435_5 = 37,
    LCM_DSI_6589_PLL_CLOCK_442 = 38,
    LCM_DSI_6589_PLL_CLOCK_448_5 = 39,
    LCM_DSI_6589_PLL_CLOCK_455 = 40,
    LCM_DSI_6589_PLL_CLOCK_461_5 = 41,
    LCM_DSI_6589_PLL_CLOCK_468 = 42,
    LCM_DSI_6589_PLL_CLOCK_474_5 = 43,
    LCM_DSI_6589_PLL_CLOCK_481 = 44,
    LCM_DSI_6589_PLL_CLOCK_487_5 = 45,
    LCM_DSI_6589_PLL_CLOCK_494 = 46,
    LCM_DSI_6589_PLL_CLOCK_500_5 = 47,
    LCM_DSI_6589_PLL_CLOCK_507 = 48,
    LCM_DSI_6589_PLL_CLOCK_513_5 = 49,
    LCM_DSI_6589_PLL_CLOCK_520 = 50,
} LCM_DSI_PLL_CLOCK;

/* --------------------------------------------------------------------------- */

typedef struct {
    LCM_COLOR_ORDER color_order;
    LCM_DBI_TRANS_SEQ trans_seq;
    LCM_DBI_PADDING padding;
    LCM_DBI_FORMAT format;
    LCM_DBI_DATA_WIDTH width;
} LCM_DBI_DATA_FORMAT;


typedef struct {
    LCM_POLARITY cs_polarity;
    LCM_POLARITY clk_polarity;
    LCM_CLOCK_PHASE clk_phase;
    unsigned int is_non_dbi_mode;

    LCM_SERIAL_CLOCK_FREQ clock_base;
    LCM_SERIAL_CLOCK_DIV clock_div;
    /* //////////////////////////////////MT6575 added params, and if lcm driver is for 6575, only care these below params */
    unsigned int css;
    unsigned int csh;
    unsigned int rd_1st;
    unsigned int rd_2nd;
    unsigned int wr_1st;
    unsigned int wr_2nd;

    unsigned int sif_3wire;
    unsigned int sif_sdi;
    LCM_POLARITY sif_1st_pol;
    LCM_POLARITY sif_sck_def;
    unsigned int sif_div2;
    unsigned int sif_hw_cs;
    /* ////////////////////////////////// */
} LCM_DBI_SERIAL_PARAMS;


typedef struct {
    /* timing parameters */
    unsigned int write_setup;
    unsigned int write_hold;
    unsigned int write_wait;
    unsigned int read_setup;
    unsigned int read_hold;
    unsigned int read_latency;
    unsigned int wait_period;
    /*only for 6575 */
    unsigned int cs_high_width;
} LCM_DBI_PARALLEL_PARAMS;


typedef struct {
    LCM_COLOR_ORDER color_order;
    LCM_DSI_TRANS_SEQ trans_seq;
    LCM_DSI_PADDING padding;
    LCM_DSI_FORMAT format;
} LCM_DSI_DATA_FORMAT;

typedef struct {
    LCM_DSI_MODE_CON mode;
    unsigned int cmd_if;
    unsigned int addr;
    unsigned int val[4];
} LCM_DSI_MODE_SWITCH_CMD;

typedef struct {
    unsigned int compress_ratio;
    unsigned int lr_mode_en;
    unsigned int vlc_disable;
    unsigned int vlc_config;
} LCM_UFOE_CONFIG_PARAMS;
/* --------------------------------------------------------------------------- */

typedef struct {
    /* common parameters for serial & parallel interface */
    unsigned int port;
    LCM_DBI_CLOCK_FREQ clock_freq;
    LCM_DBI_DATA_WIDTH data_width;
    LCM_DBI_DATA_FORMAT data_format;
    LCM_DBI_CPU_WRITE_BITS cpu_write_bits;
    LCM_DRIVING_CURRENT io_driving_current;
    LCM_DRIVING_CURRENT msb_io_driving_current;
    LCM_DRIVING_CURRENT ctrl_io_driving_current;

    /* tearing control */
    LCM_DBI_TE_MODE te_mode;
    LCM_POLARITY te_edge_polarity;
    unsigned int te_hs_delay_cnt;
    unsigned int te_vs_width_cnt;
    LCM_DBI_TE_VS_WIDTH_CNT_DIV te_vs_width_cnt_div;

    /* particular parameters for serial & parallel interface */
    LCM_DBI_SERIAL_PARAMS serial;
    LCM_DBI_PARALLEL_PARAMS parallel;
} LCM_DBI_PARAMS;


typedef struct {
    /*
       Pixel Clock Frequency = 26MHz * mipi_pll_clk_div1
       / (mipi_pll_clk_ref + 1)
       / (2 * mipi_pll_clk_div2)
       / dpi_clk_div
     */
    unsigned int mipi_pll_clk_ref;  /* 0..1 */
    unsigned int mipi_pll_clk_div1; /* 0..63 */
    unsigned int mipi_pll_clk_div2; /* 0..15 */
    unsigned int mipi_pll_clk_fbk_div;  /* PCLK=> 8: 26MHz, 10: 35MHz, 12: 40MHz */
    unsigned int dpi_clk_div;   /* 2..32 */
    unsigned int dpi_clk_duty;  /* (dpi_clk_div - 1) .. 31 */
    unsigned int PLL_CLOCK;
    unsigned int dpi_clock;
    unsigned int ssc_disable;
    unsigned int ssc_range;

    unsigned int width;
    unsigned int height;
    unsigned int bg_width;
    unsigned int bg_height;

    /* polarity parameters */
    LCM_POLARITY clk_pol;
    LCM_POLARITY de_pol;
    LCM_POLARITY vsync_pol;
    LCM_POLARITY hsync_pol;

    /* timing parameters */
    unsigned int hsync_pulse_width;
    unsigned int hsync_back_porch;
    unsigned int hsync_front_porch;
    unsigned int vsync_pulse_width;
    unsigned int vsync_back_porch;
    unsigned int vsync_front_porch;

    /* output format parameters */
    LCM_DPI_FORMAT format;
    LCM_COLOR_ORDER rgb_order;
    unsigned int is_serial_output;
    unsigned int i2x_en;
    unsigned int i2x_edge;
    unsigned int embsync;
    unsigned int lvds_tx_en;
    unsigned int bit_swap;
    /* intermediate buffers parameters */
    unsigned int intermediat_buffer_num;    /* 2..3 */

    /* iopad parameters */
    LCM_DRIVING_CURRENT io_driving_current;
    LCM_DRIVING_CURRENT msb_io_driving_current;
    LCM_DRIVING_CURRENT lsb_io_driving_current;
    LCM_DRIVING_CURRENT ctrl_io_driving_current;
} LCM_DPI_PARAMS;


/* --------------------------------------------------------------------------- */
typedef struct {
    unsigned char cmd;
    unsigned char count;
    unsigned char para_list[2];
} LCM_esd_check_item;
typedef enum {
    DUAL_DSI_NONE = 0x0,
    DUAL_DSI_CMD = 0x1,
    DUAL_DSI_VDO = 0x2,
} DUAL_DSI_TYPE;

enum MTK_PANEL_OUTPUT_MODE {
    MTK_PANEL_SINGLE_PORT = 0x0,
    MTK_PANEL_DSC_SINGLE_PORT,
    MTK_PANEL_DUAL_PORT,
};

typedef enum {
    MIPITX_PHY_LANE_0 = 0,
    MIPITX_PHY_LANE_1,
    MIPITX_PHY_LANE_2,
    MIPITX_PHY_LANE_3,
    MIPITX_PHY_LANE_CK,
    MIPITX_PHY_LANE_RX,
    MIPITX_PHY_LANE_NUM
} MIPITX_PHY_LANE_SWAP;

typedef enum {
    MIPITX_PHY_PORT_0 = 0,
    MIPITX_PHY_PORT_1,
    MIPITX_PHY_PORT_NUM
} MIPITX_PHY_PORT;

enum MTK_PANEL_SPR_MODE {
    MTK_PANEL_RGBG_BGRG_TYPE = 0x0,
    MTK_PANEL_BGRG_RGBG_TYPE,
    MTK_PANEL_RGBRGB_BGRBGR_TYPE,
    MTK_PANEL_BGRBGR_RGBRGB_TYPE,
    MTK_PANEL_RGBRGB_BRGBRG_TYPE,
    MTK_PANEL_BRGBRG_RGBRGB_TYPE,
    MTK_PANEL_EXT_TYPE,
};

enum SPR_COLOR_PARAMS_TYPE {
    SPR_WEIGHT_SET = 0,
    SPR_BORDER_SET,
    SPR_SPE_SET,
    SPR_COLOR_PARAMS_TYPE_NUM,
};

struct lcm_spr_color_params {
    enum SPR_COLOR_PARAMS_TYPE spr_color_params_type;
    unsigned int count;
    unsigned char para_list[80];
    unsigned char tune_list[80];
};

typedef struct {
    unsigned int ver; /* [7:4] major [3:0] minor */
    unsigned int slice_mode;
    unsigned int rgb_swap;
    unsigned int dsc_cfg;
    unsigned int rct_on;
    unsigned int bit_per_channel;
    unsigned int dsc_line_buf_depth;
    unsigned int bp_enable;
    unsigned int bit_per_pixel;
    unsigned int pic_height; /* need to check */
    unsigned int pic_width;  /* need to check */
    unsigned int slice_height;
    unsigned int slice_width;
    unsigned int chunk_size;
    unsigned int xmit_delay;
    unsigned int dec_delay;
    unsigned int scale_value;
    unsigned int increment_interval;
    unsigned int decrement_interval;
    unsigned int line_bpg_offset;
    unsigned int nfl_bpg_offset;
    unsigned int slice_bpg_offset;
    unsigned int initial_offset;
    unsigned int final_offset;

    unsigned int flatness_minqp;
    unsigned int flatness_maxqp;
    unsigned int rc_model_size;
    unsigned int rc_edge_factor;
    unsigned int rc_quant_incr_limit0;
    unsigned int rc_quant_incr_limit1;
    unsigned int rc_tgt_offset_hi;
    unsigned int rc_tgt_offset_lo;
} LCM_DSC_CONFIG_PARAMS;

struct lcm_cm_config_params {
    unsigned int relay;
    unsigned int cm_c00; /* [7:4] major [3:0] minor */
    unsigned int cm_c01;
    unsigned int cm_c02;
    unsigned int cm_c10;
    unsigned int cm_c11;
    unsigned int cm_c12;
    unsigned int cm_c20;
    unsigned int cm_c21;
    unsigned int cm_c22;
    unsigned int cm_coeff_round_en; /* need to check */
    unsigned int cm_precision_mask;  /* need to check */
    unsigned int bits_switch;
    unsigned int cm_gray_en;
};

struct lcm_spr_config_params {
    unsigned int enable;
    unsigned int relay;
    unsigned int rgb_swap;
    unsigned int bypass_dither;
    unsigned int postalign_en;
    unsigned int wrap_mode;
    unsigned int specialcaseen;
    unsigned int indata_res_sel;
    unsigned int outdata_res_sel;
    unsigned int padding_repeat_en;
    unsigned int postalign_6type_mode_en;
    unsigned int custom_header_en;
    unsigned int custom_header;
    unsigned int spr_format_type;
    unsigned int rg_xy_swap;
    struct lcm_spr_color_params spr_color_params[SPR_COLOR_PARAMS_TYPE_NUM];
};


typedef struct {
    LCM_DSI_MODE_CON mode;
    LCM_DSI_MODE_CON switch_mode;
    unsigned int DSI_WMEM_CONTI;
    unsigned int DSI_RMEM_CONTI;
    unsigned int VC_NUM;

    LCM_LANE_NUM LANE_NUM;
    LCM_DSI_DATA_FORMAT data_format;
    enum MTK_PANEL_OUTPUT_MODE output_mode;

    /* intermediate buffers parameters */
    unsigned int intermediat_buffer_num;    /* 2..3 */

    LCM_PS_TYPE PS;
    unsigned int word_count;

    unsigned int packet_size;
    unsigned int packet_size_mult;
    unsigned int vertical_sync_active;
    unsigned int vertical_backporch;
    unsigned int vertical_frontporch;
    unsigned int vertical_frontporch_for_low_power;
    unsigned int vertical_active_line;

    unsigned int horizontal_sync_active;
    unsigned int horizontal_backporch;
    unsigned int horizontal_frontporch;
    unsigned int horizontal_blanking_pixel;
    unsigned int horizontal_active_pixel;
    unsigned int horizontal_bllp;

    unsigned int line_byte;
    unsigned int horizontal_sync_active_byte;
    unsigned int horizontal_backporch_byte;
    unsigned int horizontal_frontporch_byte;
    unsigned int rgb_byte;

    unsigned int horizontal_sync_active_word_count;
    unsigned int horizontal_backporch_word_count;
    unsigned int horizontal_frontporch_word_count;

    unsigned char HS_TRAIL;
    unsigned char HS_ZERO;
    unsigned char HS_PRPR;
    unsigned char LPX;

    unsigned char TA_SACK;
    unsigned char TA_GET;
    unsigned char TA_SURE;
    unsigned char TA_GO;

    unsigned char CLK_TRAIL;
    unsigned char CLK_ZERO;
    unsigned char LPX_WAIT;
    unsigned char CONT_DET;

    unsigned char CLK_HS_PRPR;
    unsigned char CLK_HS_POST;
    unsigned char DA_HS_EXIT;
    unsigned char CLK_HS_EXIT;

    unsigned int pll_select;
    unsigned int pll_div1;
    unsigned int pll_div2;
    unsigned int fbk_div;
    unsigned int fbk_sel;
    unsigned int rg_bir;
    unsigned int rg_bic;
    unsigned int rg_bp;
    unsigned int PLL_CLOCK; /* PLL_CLOCK = (int) PLL_CLOCK */
    unsigned int data_rate; /* data_rate = PLL_CLOCK x 2 */
    unsigned int dsi_clock;
    unsigned int ssc_disable;
    unsigned int ssc_range;
    unsigned int cmd_null_pkt_en;
    unsigned int cmd_null_pkt_len;
    unsigned int compatibility_for_nvk;
    unsigned int cont_clock;
    unsigned int ufoe_enable;
    unsigned int dsc_enable;
    unsigned int spr_enable;
    unsigned int cm_enable;
    LCM_UFOE_CONFIG_PARAMS ufoe_params;
    LCM_DSC_CONFIG_PARAMS dsc_params;
    struct lcm_cm_config_params cm_params;
    struct lcm_spr_config_params spr_params;
    unsigned int edp_panel;
    unsigned int customization_esd_check_enable;
    unsigned int esd_check_enable;
    unsigned int lcm_int_te_monitor;
    unsigned int lcm_int_te_period;

    unsigned int lcm_ext_te_monitor;
    unsigned int lcm_ext_te_enable;

    unsigned int noncont_clock;
    unsigned int noncont_clock_period;
    unsigned int clk_lp_per_line_enable;
    LCM_esd_check_item lcm_esd_check_table[3];
    unsigned int switch_mode_enable;
    DUAL_DSI_TYPE dual_dsi_type;
    unsigned int lane_swap_en;
    MIPITX_PHY_LANE_SWAP lane_swap[MIPITX_PHY_PORT_NUM][MIPITX_PHY_LANE_NUM];

    unsigned int vertical_vfp_lp;
    unsigned int        PLL_CLOCK_lp;
    unsigned int ulps_sw_enable;
    unsigned int null_packet_en;
    unsigned int mixmode_enable;
    unsigned int mixmode_mipi_clock;
    unsigned int pwm_fps;
    unsigned int fps;
    unsigned int vact_fps;
    unsigned int send_frame_enable;

    unsigned int lfr_enable;
    unsigned int lfr_mode;
    unsigned int lfr_type;
    unsigned int lfr_skip_num;

    unsigned int ext_te_edge;
    unsigned int eint_disable;
    unsigned int IsCphy;

    unsigned int PHY_SEL0;
    unsigned int PHY_SEL1;
    unsigned int PHY_SEL2;
    unsigned int PHY_SEL3;

    unsigned int dynamic_switch_mipi;
    unsigned int vertical_sync_active_dyn;
    unsigned int vertical_backporch_dyn;
    unsigned int vertical_frontporch_dyn;
    unsigned int vertical_active_line_dyn;

    unsigned int horizontal_sync_active_dyn;
    unsigned int horizontal_backporch_dyn;
    unsigned int horizontal_frontporch_dyn;
    unsigned int horizontal_active_pixel_dyn;

    unsigned int PLL_CLOCK_dyn;     /* PLL_CLOCK = (int) PLL_CLOCK */
    unsigned int data_rate_dyn;     /* data_rate = PLL_CLOCK x 2 */
} LCM_DSI_PARAMS;

/* --------------------------------------------------------------------------- */
typedef struct {
    unsigned int round_corner_en;
    unsigned int is_notch;
    unsigned int full_content;
    unsigned int w;
    unsigned int h;
    unsigned int w_bot;
    unsigned int h_bot;
    unsigned int tp_size;
    unsigned int tp_size_l;
    unsigned int tp_size_r;
    unsigned int bt_size;
    void *lt_addr;
    void *lt_addr_l;
    void *lt_addr_r;
    void *rt_addr;
    void *lb_addr;
    void *rb_addr;
} LCM_ROUND_CORNER;

typedef struct {
    LCM_TYPE type;
    LCM_CTRL ctrl;      /* ! how to control LCM registers */
    LCM_INTERFACE_ID lcm_if;
    LCM_INTERFACE_ID lcm_cmd_if;
    /* common parameters */
    unsigned int lcm_x;
    unsigned int lcm_y;
    unsigned int width;
    unsigned int height;
    unsigned int virtual_width;
    unsigned int virtual_height;
    unsigned int io_select_mode;    /* DBI or DPI should select IO mode according to chip spec */

    /* particular parameters */
    LCM_DBI_PARAMS dbi;
    LCM_DPI_PARAMS dpi;
    LCM_DSI_PARAMS dsi;
    unsigned int physical_width;
    unsigned int physical_height;
    unsigned int od_table_size;
    void *od_table;
#ifdef MTK_ROUND_CORNER_SUPPORT
    LCM_ROUND_CORNER round_corner_params;
#endif
} LCM_PARAMS;

#define INIT_SIZE               (640)
#define COMPARE_ID_SIZE     (32)
#define SUSPEND_SIZE            (32)
#define BACKLIGHT_SIZE          (32)
#define BACKLIGHT_CMDQ_SIZE     (32)
#define MAX_SIZE            (MAX(MAX(MAX(MAX(INIT_SIZE, COMPARE_ID_SIZE), SUSPEND_SIZE), BACKLIGHT_SIZE), \
                            BACKLIGHT_CMDQ_SIZE))


typedef struct {
    char data;
    char padding[131];
} LCM_DATA_T1;


typedef struct {
    char cmd;
    char data;
    char padding[130];
} LCM_DATA_T2;


typedef struct {
    char cmd;
    char size;
    char data[128];
    char padding[2];
} LCM_DATA_T3;


typedef struct {
    char cmd;
    char location;
    char data;
    char padding[129];
} LCM_DATA_T4;


typedef struct {
    char size;
    char cmd[128];
    char padding[3];
} LCM_DATA_T5;


typedef struct {
    char func;
    char type;
    char size;
    char padding;

    union {
        LCM_DATA_T1 data_t1;
        LCM_DATA_T2 data_t2;
        LCM_DATA_T3 data_t3;
        LCM_DATA_T4 data_t4;
        LCM_DATA_T5 data_t5;
    };
} LCM_DATA;


typedef struct {
    unsigned int parsing;
    unsigned int id;
    unsigned int init_size;
    unsigned int compare_id_size;
    unsigned int suspend_size;
    unsigned int backlight_size;
    unsigned int backlight_cmdq_size;

    LCM_PARAMS params;
    LCM_DATA init[INIT_SIZE];
    LCM_DATA compare_id[COMPARE_ID_SIZE];
    LCM_DATA suspend[SUSPEND_SIZE];
    LCM_DATA backlight[BACKLIGHT_SIZE];
    LCM_DATA backlight_cmdq[BACKLIGHT_CMDQ_SIZE];
} LCM_DTS;


/* --------------------------------------------------------------------------- */

#define REGFLAG_ESCAPE_ID       (0x00)
#define REGFLAG_DELAY_MS_V3     (0xFF)

typedef struct {
    unsigned char id;
    unsigned char cmd;
    unsigned char count;
    unsigned char para_list[128];
} LCM_setting_table_V3;

/*
* dtype ---- data type
* vc        ---- virtual channel
* dlen  ---- data length
* link_state ---- HS:0  LP:1
* payload ---- payload
*/
struct dsi_cmd_desc {
    unsigned int dtype;
    unsigned int vc;
    unsigned int dlen;
    unsigned int link_state;
    char *payload;
};

typedef struct {
    void (*set_reset_pin) (unsigned int value, void *fdt);
    void (*set_chip_select) (unsigned int value);
    int (*set_gpio_out) (unsigned int gpio, unsigned int value);

    void (*udelay) (unsigned int us);
    void (*mdelay) (unsigned int ms);
    void (*rar) (unsigned int ms);

    void (*send_cmd) (unsigned int cmd);
    void (*send_data) (unsigned int data);
    unsigned int (*read_data) (void);

    void (*dsi_set_cmdq_V3) (LCM_setting_table_V3 *para_list, unsigned int size,
                             unsigned char force_update);
    void (*dsi_set_cmdq_V2) (unsigned cmd, unsigned char count, unsigned char *para_list,
                             unsigned char force_update);
    void (*dsi_set_cmdq) (unsigned int *pdata, unsigned int queue_size,
                          unsigned char force_update);
    void (*dsi_set_null) (unsigned cmd, unsigned char count, unsigned char *para_list,
                          unsigned char force_update);
    void (*dsi_write_cmd) (unsigned int cmd);
    void (*dsi_write_regs) (unsigned int addr, unsigned int *para, unsigned int nums);
    unsigned int (*dsi_read_reg) (void);
    unsigned int (*dsi_dcs_read_lcm_reg) (unsigned char cmd);
    unsigned int (*dsi_dcs_read_lcm_reg_v2) (unsigned char cmd, unsigned char *buffer,
            unsigned char buffer_size);
    void (*wait_transfer_done) (void);

    /** FIXME: GPIO mode should not be configured in lcm driver
           REMOVE ME after GPIO customization is done
    */
    int (*set_gpio_mode) (unsigned int pin, unsigned int mode);
    int (*set_gpio_dir) (unsigned int pin, unsigned int dir);
    int (*set_gpio_pull_enable) (unsigned int pin, unsigned char pull_en);
    long (*set_gpio_lcd_enp_bias)(unsigned int value, void *fdt);
    long (*set_gpio_lcm_led_en)(unsigned int value, void *fdt);
    void (*dsi_set_cmdq_V11) (void *cmdq, unsigned int *pdata, unsigned int queue_size,
                              unsigned char force_update);
    void (*dsi_set_cmdq_V22) (void *cmdq, unsigned cmd, unsigned char count,
                              unsigned char *para_list, unsigned char force_update);
    void (*dsi_swap_port) (int swap);
    void (*dsi_set_cmdq_V23) (void *cmdq, unsigned cmd, unsigned char count, unsigned char *para_list, unsigned char force_update); /* dual */
    void (*mipi_dsi_cmds_tx)(void *cmdq, struct dsi_cmd_desc *cmds);
    unsigned int (*mipi_dsi_cmds_rx)(char *out,
                                     struct dsi_cmd_desc *cmds, unsigned int len);
} LCM_UTIL_FUNCS;
typedef enum {
    LCM_DRV_IOCTL_ENABLE_CMD_MODE = 0x100,
} LCM_DRV_IOCTL_CMD;

typedef struct {
    const char *name;
    void (*set_util_funcs) (const LCM_UTIL_FUNCS *util);
    void (*get_params) (LCM_PARAMS *params);

    void (*init) (void *fdt);
    void (*suspend) (void);
    void (*resume) (void);

    /* for power-on sequence refinement */
    void (*init_power) (void *fdt);
    void (*suspend_power) (void);
    void (*resume_power) (void);

    void (*update) (unsigned int x, unsigned int y, unsigned int width, unsigned int height);
    unsigned int (*compare_id)(void *fdt);
    void (*parse_dts)(const LCM_DTS *DTS, unsigned char force_update);

    /* /////////////////////////CABC backlight related function */
    void (*set_backlight) (unsigned int level);
    void (*set_backlight_cmdq) (void *handle, unsigned int level);
    void (*set_pwm) (unsigned int divider);
    unsigned int (*get_pwm) (unsigned int divider);
    void (*set_backlight_mode) (unsigned int mode);
    /* ///////////////////////// */

    int (*adjust_fps) (void *cmdq, int fps);

    /* ///////////ESD_RECOVERY////////////////////// */
    unsigned int (*esd_check) (void);
    unsigned int (*esd_recover) (void);
    unsigned int (*check_status) (void);
    unsigned int (*ata_check) (unsigned char *buffer);
    void (*read_fb) (unsigned char *buffer);
    int (*ioctl) (LCM_DRV_IOCTL_CMD cmd, unsigned int data);
    /* /////////////////////////////////////////////// */

    void (*enter_idle)(void);
    void (*exit_idle)(void);
    void (*change_fps)(unsigned int mode);

    /* //switch mode */
    void *(*switch_mode) (int mode);
    void (*set_cmd) (void *handle, int *mode, unsigned int cmd_num);
    void (*set_lcm_cmd) (void *handle, unsigned int *lcm_cmd, unsigned int *lcm_count,
                         unsigned int *lcm_value);
    /* /////////////PWM///////////////////////////// */
    void (*set_pwm_for_mix) (int enable);
} LCM_DRIVER;


/* --------------------------------------------------------------------------- */
/* LCM Driver Functions */
/* --------------------------------------------------------------------------- */

const LCM_DRIVER *LCM_GetDriver(void);
unsigned char which_lcd_module_triple(void);

extern LCM_DRIVER hx83112b_fhdp_dsi_cmd_auo_rt4801_lcm_drv;
extern LCM_DRIVER k6895v1_64_95t_alpha_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_60hz_jdi_dphy_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_120hz_jdi_dphy_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_144hz_jdi_dphy_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_120hz_jdi_dphy_hfp_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_144hz_jdi_dphy_hfp_lcm_drv;
extern LCM_DRIVER td4330_fhdp_dsi_vdo_auo_rt5081_lcm_drv;
extern LCM_DRIVER td4330_fhdp_dsi_cmd_auo_rt5081_lcm_drv;
extern LCM_DRIVER ft8756_fhdp_dsi_vdo_auo_rt4801_lcm_drv;
extern LCM_DRIVER nt36672c_fhdp_dsi_vdo_cphy_90hz_tianma_rt4801_lcm_drv;
extern LCM_DRIVER ana6705_fhdp_samsung_dsi_cmd_dphy_lcm_drv;
extern LCM_DRIVER ana6705_fhdp_samsung_dsi_cmd_dphy_lcm_drv_v2;
extern LCM_DRIVER ana6705_wqhd_samsung_dsi_cmd_dphy_lcm_drv;
extern LCM_DRIVER ana6705_wqhd_samsung_dsi_cmd_dphy_msync2_lcm_drv;
extern LCM_DRIVER nt35595_fhd_dsi_cmd_truly_nt50358_lcm_drv;
extern LCM_DRIVER r66451_fhdp_dsi_cmd_tianma_lcm_drv;
extern LCM_DRIVER r66451_fhdp_dsi_cmd_tianma_wa_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_120hz_tianma_hfp_lcm_drv;
extern LCM_DRIVER nt36672e_fhdp_dsi_vdo_120hz_jdi_cphy_lcm_drv;
extern LCM_DRIVER nt36672egms_fhdp_dsi_vdo_120hz_jdi_cphy_lcm_drv;
extern LCM_DRIVER nt37701_fhdp_hx_dsi_cmd_dphy_lcm_drv;
extern LCM_DRIVER nt37701_fhdp_hx_dsi_cmd_dphy_120hz_lcm_drv;
extern LCM_DRIVER nt37701a_fhdp_tianma_dsi_cmd_dphy_144hz_lcm_drv;
extern LCM_DRIVER s68fc01_fhdp_vdo_samsung_aod_lcm_drv;
extern LCM_DRIVER s6e3hae_fhd_cmd_samsung_120hz_r4831a_lcm_drv;
extern LCM_DRIVER s6e3hae_wqhd_cmd_samsung_120hz_lcm_drv;
extern LCM_DRIVER nt37801_fhdplus_cmd_120hz_r4831a_lcm_drv;
//prize hjw  for panel 20220606 start
extern LCM_DRIVER td4310_fhd2160_dsi_vdo_dzx_lcm_drv;
extern LCM_DRIVER r63417_fhd_dsi_cmd_sharp55_lcm_drv;
extern LCM_DRIVER ili9882n_hdp_dsi_vdo_truly6517_lcm_drv;
extern LCM_DRIVER ili9882q_hdp_dsi_vdo_truly6517_lcm_drv;
extern LCM_DRIVER hx8399c_fhd_dsi_vdo_565_lcm_drv;
extern LCM_DRIVER ft8756_hdp_dsi_vdo_csot67_lcm_drv;
extern LCM_DRIVER ft8756_hdp_dsi_vdo_csot67_wcl_lcm_drv;
extern LCM_DRIVER ft8756_hdp_dsi_vdo_csot67_xbd_lcm_drv;
//prize hjw  for panel 20220606 end
